/*
 * Created by SharpDevelop.
 * User: MyWife
 * Date: 1/2/2003
 * Time: 7:22 AM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections.Generic;
using System.Collections;
using System.Drawing;
using System.Windows.Forms;
using popLib;
using System.IO;
using System.Collections.Specialized;
using System.Data;
using System.Threading;
using System.Diagnostics;

namespace FileMonFilter
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class MainForm
	{
		
		[STAThread]
		public static void Main(string[] args)
		{
			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);
			Application.Run(new MainForm());
		}
		
		public MainForm()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
			
		}
		
		void ButtonEvents(object sender, System.EventArgs e)
		{
			
			string command =  sender.ToString().ToLower().IndexOf("button") == -1 ? ((ToolStripMenuItem)sender).Text.ToLower() : ((Button)sender).Text.Replace("&","").ToLower();
			
			switch(command){
				case "open": executeThread( fromFile ); break;
				case "filter": executeThread( filter); break;
				case "close": break;
				case "backup": contextMenuStrip1.Show( (Control)sender, 0,0); break;
				case "registry": executeThread( backUpReg ); break;
				case "file": executeThread( backUp ); break;
				case "stop": stopThread(true); break;
			}
		}
		
		#region backup()
		void backUp(){
			string CopyCom = "COPY {0} {1} /Y\r\n";
			string RemCom  = "DEL {0}\r\n";
			string command = "\r\n\r\n:INSTALL\r\n";
			string listFile = "";
			string error = "";
			
			string folder  = FileLib.getFullPath( "BackupFile\\" + DateTime.Now.ToString("dd-MM-yyyy HH-mm-ss") );
			Directory.CreateDirectory(folder);
			
			ThreadStart ts;
			
			for( int i=0; i < lv_item.Items.Count ; i++ ){
				//copy file
				string path = "";
				ts = delegate{
					path= lv_item.Items[i].SubItems[4].Text.ToLower();
					
					//create list file
					listFile += lv_item.Items[i].ImageKey + "\r\n";
				};
				this.Invoke( ts );
				
				string file = path.Split('\\')[path.Split('\\').Length-1];
				string dest = folder + "\\" + file;
				if( File.Exists(path) && !File.Exists(dest) ){
					try{
						File.Copy( path, dest, true );
					}catch{ error += path + "\r\n"; }
				
					//create command
					path = path.Replace("c:\\windows.0","%windir%").Replace("c:\\windows","%windir%");
					command += string.Format(CopyCom, file, path );
					command  = string.Format(RemCom, path) + command;
					
					
				}
				
				if( i % 100 == 0 || i >= lv_item.Items.Count-1 ){
					setProgress( (i * 100) / (lv_item.Items.Count-1) );
				}
			}
			
			
			command  = "@ECHO OFF\r\n\r\n:MAIN_MENU\r\n@CLS\r\n" +
				"@ECHO 1. INSTALL FILES\r\n@ECHO 2. UNINSTALL\r\n@ECHO 0. Exit\r\n" +
				"@SET /A Command = 3\r\n@SET /p \"Command=>\"\r\n\r\n\r\n" +
				":ACTION\r\nIF %Command% == 0 GOTO END\r\nIF %Command% == 1 GOTO INSTALL\r\nIF %Command% == 2 GOTO UNINSTALL\r\nGOTO MAIN_MENU\r\n\r\n" +
				"\r\n\r\n:UNINSTALL\r\n" + command;
			
			FileLib.writeFile( folder + "\\_Action.bat", command );
			FileLib.writeFile( folder + "\\_List Files.txt", listFile );
			
			if( StringLib.isValid( error ) )
				FormLib.alert("There some files cannot copy!!!\r\n" + error);
			
			Process.Start( folder );
			
			stopThread(false);
		}
		
		
		
		void backUpReg(){
			string result 	= "Windows Registry Editor Version 5.00\r\n";
			string content	= "";
			
			string folder  = FileLib.getFullPath( "BackupReg\\" + DateTime.Now.ToString("dd-MM-yyyy HH-mm-ss") );
			ThreadStart ts;
			
			for( int i=0; i < lv_item.Items.Count ; i++ ){
				//copy reg item
				string path = "", val = "";
				
				ts = delegate{
					path= lv_item.Items[i].SubItems[4].Text.ToLower();
					val  = lv_item.Items[i].SubItems[6].Text.Replace("\"\"", "\"\\\"");
					
					//create list file
					content += lv_item.Items[i].ImageKey + "\r\n";
				};
				this.Invoke( ts );
				
				string key  = FileLib.getFullPath(path);
				path 		= "\r\n["+path.Remove( path.LastIndexOf(key)-1 )+"]\r\n";
				path		= path.Replace("HKCR", "HKEY_CLASSES_ROOT");
				path		= path.Replace("HKCU", "HKEY_CURRENT_USER");
				path		= path.Replace("HKLM", "HKEY_LOCAL_MACHINE");
				
				
				key  		= string.Format( "\"{0}\"={1}\r\n", key, val );
				key			= key.Replace("\"(Default)\"", "@");
				
				
				int lastIndex = result.IndexOf( path );
				if(lastIndex >= 0){
					result = result.Insert( lastIndex + path.Length, key );
				}else{
					result += path + key;
				}
				
				if( i % 100 == 0 || i >= lv_item.Items.Count-1 ){
					setProgress( (i * 100) / (lv_item.Items.Count-1) );
				}
			}
			
			
			FileLib.writeFile( folder + "\\Demo.reg", result);
			FileLib.writeFile( folder + "\\Demo_content.txt", content);
			
			Process.Start( folder );
			
			stopThread(false);
		}
		#endregion
		void fromFile(){
			string file = null;
			ThreadStart ts = delegate{ 
				FormLib.showLoading(this); 
				file = FormLib.openFile("All Files(*.*)|*.*");
				lv_item.Items.Clear();
			};
			this.Invoke(ts);
			
			
			if(file != null){
				
				string[] items = FileLib.readFile( file ).Replace("\r\n",(char)128 +"").Split((char)128);
				
				int counter = 0;
				for( int i = 0; i < items.Length; i++ ){
					string[] cols = items[i].Split('\t');
					if(cols.Length >= 5){
						ts = delegate{							
							if ( !cbx_path.Checked || (cbx_path.Checked && lv_item.FindItemWithText( cols[4] ) == null) ){
								if( checkFilter(items[i]) ){
									lv_item.Items.Add(cols[0], items[i]).SubItems.AddRange( new string[]{cols[1],cols[2],cols[3],cols[4], cols[5], cols[6]} );
									lv_item.EnsureVisible(lv_item.Items.Count-1);
									lv_item.Update();
								}
							}
						};
						this.Invoke(ts);
					}
					
					counter++;
					if( counter >= 100 || i >= items.Length-1 ){
						counter = 0;
						setProgress( (i * 100) / (items.Length-1) );
						Thread.Sleep(100);
					}
				}
			}
			
			
			stopThread(false);
		}
		
		void filter(){
			
			
			//include & exclude			
			foreach( ListViewItem item in lv_item.Items ){			
				if( !checkFilter(item.ImageKey) ){
					lv_item.Items.Remove(item);
					this.Update();					
				}									
			}				
			
			
			//group by
			if(cbx_path.Checked){
				StringCollection keyPath = new StringCollection();
				foreach( ListViewItem item in lv_item.Items ){
					string path = item.SubItems[4].Text;
					if( keyPath.IndexOf(path) == -1 ){
						keyPath.Add(path);
					}else{
						lv_item.Items.Remove(item);
						this.Update();
					}
				}								
			}
			
			stopThread(false);
			
		}
		
		string[] exFilter, inFilter;
		void initFilter(){
			exFilter = StringLib.isValid(txt_exclude.Text) ? StringLib.splitByAny( txt_exclude.Text.ToLower(), ";,|") : new string[0];
			inFilter = StringLib.isValid(txt_include.Text) ? StringLib.splitByAny( txt_include.Text.ToLower(), ";,|") : new string[0];
		}
		
		bool checkFilter(string item){
			//exclude
			foreach( string filter in exFilter)
				if( StringLib.isValid(filter) && item.ToLower().IndexOf(filter) >= 0 ) return false;
			
			//include			
			if( inFilter.Length > 0 ){
				foreach( string filter in inFilter)
					if( StringLib.isValid(filter) && item.ToLower().IndexOf(filter) >= 0 ) return true;
				
				return false;
			}			
			return true;
		}
		
		void setProgress(int percent){
			ThreadStart ts = delegate{
				progressBar1.Value = percent > 100 ? 100 : percent;
				using( Graphics gr = progressBar1.CreateGraphics() ){
					string content = progressBar1.Value + " %";
					SizeF contentSize = gr.MeasureString( content, SystemFonts.DefaultFont );
					gr.DrawString( content, SystemFonts.DefaultFont, Brushes.Black, new PointF( progressBar1.Width/2 - contentSize.Width/2, progressBar1.Height/2 - contentSize.Height/2 ) );
				}				
			};
			
			this.Invoke( ts );
		}
	
		Thread process;
		delegate void ExeDelegate();
		void executeThread( ExeDelegate func ){
			initFilter();
			FormLib.showLoading(this);
			
			process = new Thread( new ThreadStart( func ) );
			process.IsBackground = true;
			process.Start();
			
			button1.Enabled = button2.Enabled = button3.Enabled = button4.Enabled = false;
			button5.Enabled = true;
		}
		
		void stopThread(bool stop){
			
			ThreadStart ts = delegate{
				FormLib.hideLoading(this);			
				button1.Enabled = button2.Enabled = button3.Enabled = button4.Enabled = true;
				button5.Enabled = false;
			};
			this.Invoke(ts);
			
			if( stop && process != null ){
				process.Abort();
				process = null;
			}
		}
		
		void MainFormKeyDown(object sender, KeyEventArgs e)
		{
			if(e.KeyValue == 27)
				ButtonEvents( button5, new EventArgs() );
		}
	}
}
